<template>
	<div class="upload-container">
		<!-- 上传按钮区域 -->
		<div class="upload-trigger" @click="triggerUpload">
			<div v-if="!imageUrl" class="upload-placeholder">
				<i class="upload-icon">+</i>
			</div>
			<img v-else :src="imageUrl" class="preview-image" />
		</div>

		<!-- 隐藏的文件输入框 -->
		<input
			ref="fileInput"
			type="file"
			accept="image/*"
			class="file-input"
			@change="handleFileChange" />
	</div>
</template>

<script setup lang="ts">
import { ref } from 'vue';

// 定义组件属性
const props = defineProps<{
	maxSize?: number; // 最大文件大小，单位：MB，默认1MB
}>();

// 定义事件
const emit = defineEmits<{
	'upload-success': [data: { base64: string; url: string }];
	'upload-error': [error: string];
}>();

// 组件状态
const fileInput = ref<HTMLInputElement | null>(null);
const imageUrl = ref<string>('');

// 触发文件选择
const triggerUpload = () => {
	fileInput.value?.click();
};

// 处理文件改变事件
const handleFileChange = (event: Event) => {
	const input = event.target as HTMLInputElement;
	const file = input.files?.[0];

	if (!file) {
		return;
	}

	// 检查文件大小
	const maxSize = (props.maxSize || 1) * 1024 * 1024; // 转换为字节
	if (file.size > maxSize) {
		emit('upload-error', `文件大小不能超过${props.maxSize || 1}MB`);
		resetInput();
		return;
	}

	// 检查文件类型
	if (!file.type.startsWith('image/')) {
		emit('upload-error', '请上传图片文件');
		resetInput();
		return;
	}

	// 读取文件
	const reader = new FileReader();
	reader.onload = (e) => {
		const base64 = e.target?.result as string;
		const url = URL.createObjectURL(file);
		imageUrl.value = url;
		emit('upload-success', { base64, url });
	};

	reader.onerror = () => {
		emit('upload-error', '文件读取失败');
		resetInput();
	};

	reader.readAsDataURL(file);
};

// 重置输入框
const resetInput = () => {
	if (fileInput.value) {
		fileInput.value.value = '';
	}
};
</script>

<style scoped lang="scss">
.upload-container {
	display: inline-block;
}

.upload-trigger {
	width: 58px;
	height: 58px;
	border: 1px dashed #d9d9d9;
	border-radius: 8px;
	cursor: pointer;
	transition: border-color 0.3s;
	display: flex;
	align-items: center;
	justify-content: center;
	overflow: hidden;

	&:hover {
		border-color: #1890ff;
	}
}

.upload-placeholder {
	text-align: center;
	color: #999;
}

.upload-icon {
	font-size: 16px;
	color: #999;
}

.upload-text {
	margin-top: 2px;
	font-size: 12px;
}

.preview-image {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.file-input {
	display: none;
}
</style>
